// 这个是客户端
// 干什么 ??
// 1. 发单词给服务器让它处理翻译
// 2. 接受翻译后的结果
// 所以 , 也要从网络中获取信息 , 要创建网络
// 客户端要知道服务器端才能通信

#include <iostream>
#include "Log.hpp"
#include "Common.hpp"
#include "InetAddr.hpp"

using namespace LogModel;

void Usage()
{
    LOG(LogLevel::ERROR) << "Usage : ./clinet server_ip server_port ";
}

// ./client server_ip server_port
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage();
        exit(Usage_error);
    }

    // 获取命令行 server_ip server_port
    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]);

    // 1 . 创建套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        LOG(LogLevel::FATAL) << "socket error !";
        exit(Socket_error);
    }
    LOG(LogLevel::INFO) << "socket success !";

    // 2. 绑定 -- 客户端不用显示绑定 , 系统自动绑定

    // 3. 构建网络信息 , 客户端有服务器 ip 和 端口
    // 本地转网络
    InteAddr server(server_ip, server_port);

    // 3. 发消息 -- 发英文 , 让服务器帮我翻译成中文 , 我接受

    while (true)
    {
        std::string input;
        std::cout << "Please Enter#";
    std:
        getline(std::cin, input); // 从 cin 中获取 input

        // 1. sendto
        ssize_t num = sendto(sockfd, input.c_str(), input.size(), 0, server.NetAddrPtr(), server.NetAddrLen());
        if (num > 0)
        {
            LOG(LogLevel::INFO) << "clinet sendto : " << input;
            // 2. 收

            char buffer[64];
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);
            if (n > 0)
            {
                //网络转本地 
                InteAddr local(peer);
                buffer[n] = 0;
                LOG(LogLevel::INFO) << "recv [ " << local.GetIp() << ":" << local.GetPort() 
                                    << " ] -> { " << buffer << " }" ;
            }
        }
    }

    return 0;
}